package com.yuncommunity.runcircle.db;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;

import com.amap.api.location.AMapLocation;
import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper;
import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.dao.GenericRawResults;
import com.j256.ormlite.support.ConnectionSource;
import com.j256.ormlite.table.TableUtils;
import com.oldfeel.utils.DialogUtil;
import com.oldfeel.utils.StringUtil;
import com.yuncommunity.runcircle.conf.Constants;
import com.yuncommunity.runcircle.conf.UserInfo;
import com.yuncommunity.runcircle.item.HistoryItem;
import com.yuncommunity.runcircle.item.LocationItem;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by oldfeel on 11/23/15.
 */
public class DBHelper extends OrmLiteSqliteOpenHelper {
    private static DBHelper dbHelper;
    private Dao<LocationItem, ?> dao;
    private Context context;

    public static DBHelper getInstance(Context context) {
        if (dbHelper == null) {
            dbHelper = new DBHelper(context);
        }
        return dbHelper;
    }

    public DBHelper(Context context) {
        super(context, Constants.DB_NAME, null, Constants.DB_VERSION);
        this.context = context;

        try {
            dao = getDao(LocationItem.class);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onCreate(SQLiteDatabase database, ConnectionSource connectionSource) {
        try {
            TableUtils.createTable(connectionSource, LocationItem.class);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onUpgrade(SQLiteDatabase database, ConnectionSource connectionSource, int oldVersion, int newVersion) {
        try {
            TableUtils.dropTable(connectionSource, LocationItem.class, true);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        onCreate(database, connectionSource);
    }

    /**
     * 结束跑步
     *
     * @param stepsAll
     * @param time
     */
    public LocationItem endRun(float stepsAll, long time) {
        try {
            Dao<LocationItem, ?> locationItemDao = getDao(LocationItem.class);
            LocationItem lastLocationItem = locationItemDao.queryBuilder().orderBy("time", false).where().eq("userId", getUserId()).queryForFirst();
            if (lastLocationItem != null) {
                if (lastLocationItem.type == LocationItem.TYPE_START) { // 结束跑步时的最后一个点是开始点,则删除
                    locationItemDao.delete(lastLocationItem);
                    DialogUtil.getInstance().showToast(context, "结束点与开始点相同,此次跑步记录无效");
                } else {
                    lastLocationItem.type = LocationItem.TYPE_END;
                    LocationItem startItem = locationItemDao.queryBuilder().orderBy("time", false).where().eq("userId", getUserId()).and().eq("type", LocationItem.TYPE_START + "").queryForFirst();
                    lastLocationItem.duration = time * 1000;
                    lastLocationItem.allDistance = getAllDistance(startItem);
                    lastLocationItem.speed = lastLocationItem.allDistance / 1000 / ((double) time / 60 / 60);
                    lastLocationItem.step = (int) (stepsAll - startItem.step);
                    locationItemDao.update(lastLocationItem);
                }
            }
            return lastLocationItem;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 开始跑步
     *
     * @param amapLocation
     * @param stepsAll
     */
    public LocationItem startRun(AMapLocation amapLocation, float stepsAll) {
        try {
            LocationItem locationItem = new LocationItem();
            locationItem.userId = getUserId();
            locationItem.lat = amapLocation.getLatitude();
            locationItem.lon = amapLocation.getLongitude();
            locationItem.time = System.currentTimeMillis();
            locationItem.date = StringUtil.getCurrentDate();
            locationItem.type = LocationItem.TYPE_START;
            locationItem.step = (int) stepsAll;
            dao.create(locationItem);
            return locationItem;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    public LocationItem saveLocation(AMapLocation amapLocation) {
        try {
            LocationItem lastItem = dao.queryBuilder().orderBy("time", false).queryForFirst();
            if (lastItem != null) {
                LocationItem item = new LocationItem();
                item.userId = getUserId();
                item.lat = amapLocation.getLatitude();
                item.lon = amapLocation.getLongitude();
                item.time = System.currentTimeMillis();
                item.date = StringUtil.getCurrentDate();
                item.distance = item.initDistance(lastItem);
                dao.create(item);
                return item;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    private int getUserId() {
        return UserInfo.getInstance().getUserId();
    }

    private double getAllDistance(LocationItem startItem) {
        try {
            // return the orders with the sum of their amounts per account
            GenericRawResults<String[]> rawResults =
                    dao.queryRaw(
                            "select sum(distance) from locationitem where userId=? and time >= ?", getUserId() + "", startItem.time + "");
            // page through the results
            String[] result = rawResults.getFirstResult();
            rawResults.close();
            if (result[0] != null) {
                return Double.valueOf(result[0]);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return 0;
    }

    /**
     * 获取这次跑步的坐标点
     *
     * @param historyItem
     * @return
     */
    public List<LocationItem> getLocationList(HistoryItem historyItem) {
        try {
            LocationItem endItem = dao.queryBuilder().where().eq("id", historyItem.id).queryForFirst();
            if (endItem != null) {
                LocationItem startItem = dao.queryBuilder().orderBy("time", false).where().eq("userid", getUserId()).and().le("time", endItem.time).and().eq("type", LocationItem.TYPE_START).queryForFirst();
                return dao.queryBuilder().where().eq("userid", getUserId()).and().ge("time", startItem.time).and().le("time", endItem.time).query();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return new ArrayList<>();
    }

    /**
     * 当前跑步的位置列表
     *
     * @return
     */
    public List<LocationItem> getCurrentRunLocationList() {
        try {
            LocationItem startItem = dao.queryBuilder().orderBy("time", false).where().eq("userid", getUserId()).and().le("time", System.currentTimeMillis()).and().eq("type", LocationItem.TYPE_START).queryForFirst();
            return dao.queryBuilder().where().eq("userid", getUserId()).and().ge("time", startItem.time).and().le("time", System.currentTimeMillis()).query();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return new ArrayList<>();
    }

    public void update(LocationItem endItem) {
        try {
            dao.update(endItem);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
